package GameEngine;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.Timer;
import Main.Main;


public class Game
{
	private Timer timer, speedUpTimer;
	private boolean isStarted;
	private boolean isPaused;
	private boolean musicOn;
	private int gameSpeed;
	private int level;
	private Boat boat;
	private AreaController areaController;
	private RiverController riverController;
	private SoundManager sound;
	private ImageIcon background;
	private ImageIcon hicon;
	private int overflow;
	private int keyPressCounter;
	private boolean gameOver;
	private boolean speedUp;
	
	/**
	 * Initiliaze the attributes for start the new game
	 */
	public Game()
	{
		keyPressCounter = 0;
		timer = null;
		musicOn = true;
		gameSpeed = 60;
		isStarted = false;
		isPaused = false;
		level = 0;
		boat = new Boat();
		areaController = new AreaController();
		riverController = new RiverController();
		sound = new SoundManager();
		background = Main.GUI.getImages().getRiverBackgroundImage();
		hicon = Main.GUI.getImages().getHealthIcon();
		overflow = 0;
		gameOver = false;
	}

	/**
	 * Starts the game by initializing the map and setting the timer.
	 */
	public void start()
	{
		riverController.initMap();
		this.timer = new Timer(this.gameSpeed,new ActionListener() {
	          public void actionPerformed(ActionEvent e) 
	          {
	              updateTimer(Main.mygame.overflow);
	          }
	    });
		this.isStarted = true;
		this.timer.start();
	}
	
	/**
	 * Sets gameOver = true and stops the timer
	 */
	public void gameOver()
	{
		gameOver = true;
		Main.GUI.setGameMode(false);
		this.timer.stop();
	}
	
	/**
	 * Execute the game actions during the game.
	 * @param overflow determines the pixels between the rows for the objects.
	 */
	public void updateTimer(int overflow)
	{
		
		getBoat().moveRight();
		getBoat().moveLeft();
		getBoat().moveForward();
		getBoat().moveBack();
		Main.mygame.getAreaController().checkIntersection();
		if (getBoat().isJumped())
		{
			getBoat().setJumpTime((getBoat().getJumpTime() + 9) % 180);
			if (Math.sin(getBoat().getJumpTime()*Math.PI/180)==0)
			{
				getBoat().setJumped(false);
				getBoat().setJumpTime(0);
			}
		}
		this.riverController.renderMap(overflow);
		areaController.checkIntersection();
		if ((level%10)==0)
		{
			if (level%10==0)
			{
				if( getBoat().getRotdegree() > 0)
					getBoat().setRotdegree(getBoat().getRotdegree() - 1);
				if( getBoat().getRotdegree() < 0)
					getBoat().setRotdegree(getBoat().getRotdegree() + 1);
			}
			level++;
		}
		setOverflow((overflow+1)%20);
	}

	/**
	 * Increase the game speed for each time the user presses 20 keys
	 */
	public void checkSpeed()
	{
		if (keyPressCounter%20==0)
		{
			setGameSpeed((int)(getGameSpeed()*0.9));
			timer.setDelay(getGameSpeed());
			getSound().playSpeedUp();
			this.speedUp = true;
			this.speedUpTimer = new Timer(1800, new ActionListener(){
				public void actionPerformed(ActionEvent e){
					Main.mygame.setSpeedUp(false);
					Main.mygame.speedUpTimer.stop();
				}
			});
			this.speedUpTimer.start();
		}
	}
	
	/**
	 * Renders game panel on the given graphics object
	 * @param g is the graphics object of the game screen
	 */
	public void renderGamePanel(Graphics g)
	{
		int height = 0;
		if( getBoat().getLocation().getY() < 250)
			height = 449;
		g.setColor(new Color(Color.BLACK.getRed(), Color.BLACK.getGreen(), Color.BLACK.getBlue(), 120));
		g.fillRect(0, height, 700, 40);
		g.setColor(Color.WHITE);
		g.setFont(new Font("Helvetica", Font.BOLD, 22));
		g.drawString("SCORE: " + getBoat().getScore(), 10, 25 + height);
		g.drawString("LIFE: ", 183, 25 + height);
		g.setColor( new Color(250, 100, 100, 150));
		g.fillRect(250, 7 + height, 300, 20);
		g.setColor( new Color(50, 200, 100, 150));
		g.fillRect(250, 7 + height, getBoat().getHealthPercent()*3, 20);
		g.setColor(Color.WHITE);
		g.drawString("" + getBoat().getHealthLevel() + " x ", 582 ,25 + height);
		g.drawImage(Main.GUI.getImages().healthIcon.getImage(), 632, 0 + height, 30,30, null);
		if( this.isPaused){
			g.setColor(new Color(Color.BLACK.getRed(), Color.BLACK.getGreen(), Color.BLACK.getBlue(), 120));
			g.fillRect(0, 0, 700, 519);
			g.setColor(Color.RED);
			g.setFont(new Font("Helvetica", Font.BOLD, 30));
			g.drawString("GAME PAUSED", 240, 230);
		}
	}
	
	
	public Timer getTimer() {
		return timer;
	}

	public void setTimer(Timer timer) {
		this.timer = timer;
	}

	public boolean isMusicOn() {
		return musicOn;
	}
	
	public void setMusicOn() {
		this.musicOn = true;
		sound.playAmbientSound();
	}

	public void setMusicOff() {
		this.musicOn = false;

		try{
		sound.close();
		}catch(Exception e){
			System.out.println("Music is not closed!");
		}
	}

	public int getGameSpeed() {
		return gameSpeed;
	}

	public void setGameSpeed(int gameSpeed) {
		this.gameSpeed = gameSpeed;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public Boat getBoat(){
		return this.boat;
	}
	
	public int getOverflow(){
		return this.overflow;
	}
	public void setOverflow(int overflow){
		this.overflow = overflow;
	}

	public void setBoat(Boat boat) {
		this.boat = boat;
	}

	public AreaController getAreaController() {
		return areaController;
	}

	public void setAreaController(AreaController areaController) {
		this.areaController = areaController;
	}

	public RiverController getRiverController() {
		return riverController;
	}

	public void setRiverController(RiverController riverController) {
		this.riverController = riverController;
	}

	public SoundManager getSound() {
		return sound;
	}

	public void setSound(SoundManager sound) {
		this.sound = sound;
	}

	public ImageIcon getBackground() {
		return background;
	}

	public void setBackground(ImageIcon background) {
		this.background = background;
	}

	public ImageIcon getHicon() {
		return hicon;
	}

	public void setHicon(ImageIcon hicon) {
		this.hicon = hicon;
	}

	public boolean isStarted() {
		return isStarted;
	}

	public void setStarted(boolean isStarted) {
		this.isStarted = isStarted;
	}

	public int getKeyPressCounter() {
		return keyPressCounter;
	}

	public void setKeyPressCounter(int keyPressCounter) {
		this.keyPressCounter = keyPressCounter;
	}

	public boolean isPaused() {
		return isPaused;
	}

	public void setPaused(boolean isPaused) {
		this.isPaused = isPaused;
	}

	public boolean isGameOver() {
		return gameOver;
	}

	public void setGameOver(boolean gameOver) {
		this.gameOver = gameOver;
	}

	public boolean isSpeedUp() {
		return speedUp;
	}

	public void setSpeedUp(boolean speedUp) {
		this.speedUp = speedUp;
	}
	
	
}
